package logger

import (
	"fmt"
	"gopkg.in/natefinch/lumberjack.v2"
	"os"
	"starry_sky/internal/config"
	"starry_sky/internal/core"
	"starry_sky/internal/tools"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var SystemLogger *zap.SugaredLogger

func InitLoggers() {
	config.InitLogConfig()
	initLogger(config.LogConfig)
}

func initLogger(config *config.AllLogConfig) {
	if exists, err := tools.PathExists(config.SystemLogConfig.Path); err != nil {
		fmt.Println(err)
	} else {
		if !exists {
			err := os.MkdirAll(config.SystemLogConfig.Path, os.ModePerm)
			if err != nil {
				fmt.Println("日志文件夹创建错误！")
			}
		}
	}
	//日志级别
	loggerLevel := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { //error级别
		return lev >= zapcore.Level(config.SystemLogConfig.LogLevel)
	})
	zcore := zapcore.NewCore(GetEncoder(), GetLoggerWriterSyncer(config.SystemLogConfig.LoggerName, config.SystemLogConfig.OutputMode, config.SystemLogConfig.Path, config.SystemLogConfig.FilePrefix), loggerLevel)
	if config.SystemLogConfig.ShowCaller {
		config.SystemLogConfig.Logger = zap.New(zcore, zap.AddCaller(), zap.AddCallerSkip(1))
	} else {
		config.SystemLogConfig.Logger = zap.New(zcore)
	}
	SystemLogger = config.SystemLogConfig.Logger.Sugar()
}

// GetEncoder 日志存储的编码方式
func GetEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	// encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
	return zapcore.NewConsoleEncoder(encoderConfig)
}

func GetLoggerWriterSyncer(loggerName string, outputMode string, path string, filePrefix string) zapcore.WriteSyncer {
	switch outputMode {
	case core.Console.GetValue():
		return zapcore.AddSync(os.Stdout)
	case core.File.GetValue():
		return GetLoggerWriterSyncerForFile(path, filePrefix)
	case core.All.GetValue():
		return zapcore.NewMultiWriteSyncer(GetLoggerWriterSyncerForFile(path, filePrefix), zapcore.AddSync(os.Stdout))
	default:
		//日志创建失败，强制退出程序
		panic(fmt.Sprintf("%s：日志输出方式配置错误\n", loggerName))
	}
}

// GetLoggerWriterSyncerForFile 指定用日存储文件位置
func GetLoggerWriterSyncerForFile(path string, filePrefix string) zapcore.WriteSyncer {
	logger := lumberjack.Logger{
		Filename:   fmt.Sprintf("%s/%s_%s.log", path, filePrefix, time.Now().Format("2006-01-02")),
		MaxSize:    3, // megabytes
		MaxAge:     7, // days
		MaxBackups: 10,
		LocalTime:  true,
		Compress:   true, // disabled by default
	}
	return zapcore.AddSync(&logger)
}

func HasError(err error, msg ...string) bool {
	if err != nil {
		if msg != nil {
			SystemLogger.Errorf("%s : %s", msg[0], err.Error())
		} else {
			SystemLogger.Errorln(err.Error())
		}
		return true
	}
	return false
}

func SysInfoF(template string, args ...interface{}) {
	SystemLogger.Infof(template, args...)
}
func SysWarnF(template string, args ...interface{}) {
	SystemLogger.Warnf(template, args...)
}
func SysErrorF(template string, args ...interface{}) {
	SystemLogger.Errorf(template, args...)
}
